/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package API_Systeme.Proxy;

import API_Db.API_Db_Seance;
import API_Systeme.API_Systeme_Compte;
import domain.Categorie;
import domain.Observer.Seance;
import java.sql.Timestamp;
import java.util.List;

/**
 *
 * @author Wan
 */
public class API_Systeme_Seance implements IAPI_Systeme_Proxy {

    /**
     * Instance de la classe API_Db_Seance permetant l acces a la bdd
     */
    private API_Db_Seance API_Db_S = new API_Db_Seance();

    /**
     * Creatin d une seance
     * @param s
     * @throws Exception 
     */
    public void creerSeance(Seance s, int id_utilisateur) throws Exception {

        s.setEtat(Seance.PRE_OUVERTURE);
        s.getProduit().setId_produit(API_Db_S.ajouterProduitDB(s.getProduit()));

        API_Db_S.ajouterImageProduitDB(s.getProduit().getId_produit(), s.getProduit().getImages());
        int id_seance = API_Db_S.creerSeanceDB(s);
        s.setId_seance(id_seance);
        if (id_seance == 0) {
            throw new Exception("Erreur lors de l'enregistrement de la seance");
        }
    }

    /**
     * Retourne une liste de n seances correspondant a la condition
     * @param condition
     * @param nbSeance
     * @param numPage
     * @return Liste de Seance
     * @throws Exception 
     */
    public List<Seance> listerSeance(String condition, int nbSeance, int numPage) throws Exception {
        return API_Db_S.listerSeanceDB(condition, nbSeance, numPage);
    }

    /**
     * Retoune le nombre de page de seance correspondant a cette condition et ce nombre de seance par page
     * @param condition
     * @param nbSeance nombre de seance par page
     * @return nombre de pages
     */
    public int getNbPages(String condition, int nbSeance) throws Exception {
        return API_Db_S.getNbPagesDB(condition, nbSeance);
    }

    /**
     * Annulation de la seance
     * @param id_seance
     * @throws Exception 
     */
    public void annulerSeance(int id_seance) throws Exception {
        Seance seance = API_Db_S.getSeanceById(id_seance);
        Timestamp today = new Timestamp(new java.util.Date().getTime());

        if (seance.getEtat() == 2) {
            throw new Exception("Impossible d'annuler la seance, elle est déjà ouverte");
        }

        changerEtatSeance(id_seance, Seance.ANNULE);
    }

    /**
     * Changement d etat de la seance 
     * @param id_seance
     * @param etat
     * @throws Exception 
     */
    public void changerEtatSeance(int id_seance, int etat) throws Exception {
        if (API_Db_S.changerEtatSeanceDB(id_seance, etat) == 0) {
            throw new Exception("La seance n'existe pas");
        }
    }

    /**
     * Fonction appele par un cron serveur qui permet la finalisation des seances
     * @param id_seance
     * @return 
     */
    public void finaliserSeance(Seance s) throws Exception {
        Double montant = API_Db_S.getMeilleurEnchereDB(s.getId_seance());

        if (montant < s.getReserve()) {
            changerEtatSeance(s.getId_seance(), Seance.NON_VENDU);
        } else {
            changerEtatSeance(s.getId_seance(), Seance.TERMINE);

            API_Systeme_Compte API_Sys_C = new API_Systeme_Compte();

            int id_acheteur = API_Db_S.getMeilleurEncherisseurDB(s.getId_seance()).getIdUtilisateur();

            API_Sys_C.transfertCompte(s.getId_vendeur(), id_acheteur, montant);
        }
        s.notifyObserver();
    }

    /**
     * Fonction appele par un cron serveur qui permet l ouverture des seances
     * @param id_seance
     * @throws Exception 
     */
    public void ouvrirSeance(int id_seance) throws Exception {
        changerEtatSeance(id_seance, Seance.EN_COURS);
    }

    /**
     * L utilisateur rejoint la seance
     * @param id_seance
     * @param id_utilisateur
     * @throws Exception 
     */
    public void rejoindeSeance(int id_seance, int id_utilisateur) throws Exception {
        if (API_Db_S.getSeanceById(id_seance).getId_vendeur() == id_utilisateur) {
            throw new Exception("Imposible vous etes le vendeur");
        }
        
        if (0 == id_utilisateur) {
            throw new Exception("Veuillez vous identifiez.");
        }

        API_Db_S.rejoindreSeanceDB(id_seance, id_utilisateur);
    }

    @Override
    public void quitterSeance(int id_seance, int id_utilisateur) throws Exception {
        if (API_Db_S.quitterSeanceDB(id_seance, id_utilisateur) == 0) {
            throw new Exception("L'utilisateur ne participe pas à cette séance");
        }
    }

    @Override
    public void posterMessage(int id_seance, int id_utilisateur, String message) throws Exception {
        if (API_Db_S.posterMessageDB(id_seance, id_utilisateur, message) == 0) {
            throw new Exception("Erreur lors de la sauvegarde du message");
        }
    }

    //TODO synchronized
    @Override
    public void encherir(int id_seance, int id_utilisateur, double prix) throws Exception {
        if (API_Db_S.encherirDB(id_seance, id_utilisateur, prix) == 0) {
            throw new Exception("Erreur lors de la sauvegarde de l'enchère");
        }
    }

    /**
     * Retourne l'enchere minimum a effectuer
     * @param id_seance
     * @return
     * @throws Exception 
     */
    public double getEnchereSuivante(int id_seance) throws Exception {
        double courante = API_Db_S.getMeilleurEnchereDB(id_seance);
        double ecartMin = Math.ceil(courante / 100);
        if (courante != 0) {
            return courante + ecartMin;
        } else {
            return API_Db_S.getSeanceById(id_seance).getPrix_depart();
        }
    }

    /**
     * Renvoi la liste de toutes les categorie de la bdd
     * @return
     * @throws Exception 
     */
    public List<Categorie> getAllCategorie() throws Exception {
        return API_Db_S.getAllCategorie();
    }

    /**
     * Test si l utilisateur participe a la seance
     * @return 
     * @throws Exception 
     */
    public boolean participeASeance(int id_seance, int id_utilisateur) throws Exception {
        return API_Db_S.participeASeance(id_seance, id_utilisateur);
    }
}
